home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
001-025
/
scopedisk1
/
color_twiddler
/
colorreq.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-18
|
17KB
|
722 lines
/* I had nothing to do with this section other than removing a couple of */
/* Latticisms. -- John */
/* This color requester was hacked out of a Mandelbrot program by
RJ Mical, Mike Ballantyne and R French. I'm not sure which one of these
deserves most of the credit for the colour requester but I suspect RJ Mical.
I merely neatened up the code, fixed it so it wouldn't go glitchy with
fast ram, got rid of 33 unnecessary gadgets, put in the numeric display of
the rgb values of the current colour, fixed the display so it looks
reasonable in less than 5 bit planes (it used to always try to show 32
coloured squares, even if it only had two colours to work with), and made it
as easy as possible to call from any program. To access it from your
program simply put in the statement DoColorWindow(screen) where screen is
a pointer to your screen. That's it. This program (subroutine actually)
may be freely distributed as long as this notice giving credit to the four
contributing authors is left intact. Pls address any correspondence
regarding this program to :
Bruce Dawson
c/o CantorSoft.
407-1280 Haro St,
Vancouver
B.C.
V6E1E8
*/
#include <clib/macros.h>
#include <exec/types.h>
#include <exec/tasks.h>
#include <exec/devices.h>
#include <devices/keymap.h>
#include <graphics/copper.h>
#include <graphics/display.h>
#include <graphics/gels.h>
#include <graphics/regions.h>
#include <hardware/blit.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
/* Lattice sticks these two in a subdirectory. -- John */
#include <ctype.h>
#include <stdio.h>
#include <libraries/dos.h>
/* === the definitions for the ColorWindow =============================== */
#define KNOB_BODY 0x1111
#define WINDOW_WIDTH 208
#define WINDOW_HEIGHT 106
#define WINDOW_LEFT (320 - WINDOW_WIDTH)
#define WINDOW_TOP (200 - WINDOW_HEIGHT)
#define CHARACTER_WIDTH 8
#define CHARACTER_HEIGHT 8
#define CURRENT_LEFT 6
#define CURRENT_TOP 16
#define CURRENT_RIGHT (CURRENT_LEFT + 15)
#define CURRENT_BOTTOM (CURRENT_TOP + 29)
#define COLORS_TOP 55
#define PROP_LEFT 38
#define PROP_TOP 14
#define PROP_WIDTH 149
#define PROP_HEIGHT 10
#define ACTIONS_LEFT 141
#define ACTIONS_TOP 51
#define ACTIONS_WIDTH (CHARACTER_WIDTH * 6 + 4)
#define ACTIONS_HEIGHT 9
/* GREEN and RED are out of order. Do you wonder why? Some day I'll
* tell you. =RJ=
*/
#define COLOR_COPY 0
#define COLOR_RANGE 1
#define COLOR_OK 2
#define COLOR_CANCEL 3
#define COLOR_GREEN 4
#define COLOR_RED 5
#define COLOR_BLUE 6
#define COLOR_GADGETS_COUNT 7
/***************************************************************************
*
* Color window template initialization and routines,
* for colorwindow and cyclewindow
*
* Throughout this file, the COLOR_RED and COLOR_GREEN gadgets are in the
* opposite order you would expect.
*
****************************************************************************/
struct TextAttr safefont = {
(UBYTE *)"topaz.font",
TOPAZ_EIGHTY,
0,
0,
};
struct IntuiText string =
{
1, 0, /* frontpen, backpen */
JAM2, /* drawmode */
0,0, /* leftedge, topedge */
&safefont, /* pointer to font */
NULL, /* pointer to text data */
NULL /* next text */
};
SHORT actions_corners[] = {
-1, -1,
-1, ACTIONS_HEIGHT,
ACTIONS_WIDTH, ACTIONS_HEIGHT,
ACTIONS_WIDTH, -1,
-1, -1,
};
struct Border actions_border = {
0, 0,
1, 0,
JAM1,
5,
actions_corners,
NULL,
};
struct IntuiText actions_text[4] = {
{ /* "COPY" */
1, 0,
JAM2,
2 + CHARACTER_WIDTH, 1,
&safefont,
(UBYTE *)"COPY",
NULL,
},
{ /* "RANGE" */
1, 0,
JAM2,
2 + (CHARACTER_WIDTH >> 1), 1,
&safefont,
(UBYTE *)"RANGE",
NULL,
},
{ /* "OK" */
1, 0,
JAM2,
2 + (CHARACTER_WIDTH << 1), 1,
&safefont,
(UBYTE *)"OK",
NULL,
},
{ /* "CANCEL" */
1, 0,
JAM2,
2, 1,
&safefont,
(UBYTE *)"CANCEL",
NULL,
},
};
/* ======================================================================== */
/* ======================================================================== */
/* ======================================================================== */
/* RJM anchor */
struct Image ColorPropsImages[3];
struct Image ColorImage =
{
CURRENT_LEFT, COLORS_TOP, /* left edge, top edge */
15, 10, 0, /* width, height, depth */
NULL, /* image data */
0, /* planepick */
0, /* planeonoff - set later */
NULL /* NextImage */
};
struct PropInfo ColorPropsInfos[3] = {
{ /* COLOR_GREEN */
AUTOKNOB | FREEHORIZ,
0,
0,
KNOB_BODY,
0,
0, 0, 0, 0, 0, 0,
},
{ /* COLOR_RED */
AUTOKNOB | FREEHORIZ,
0,
0,
KNOB_BODY,
0,
0, 0, 0, 0, 0, 0,
},
{ /* COLOR_BLUE */
AUTOKNOB | FREEHORIZ,
0,
0,
KNOB_BODY,
0,
0, 0, 0, 0, 0, 0,
},
};
struct Gadget gadglist[COLOR_GADGETS_COUNT] = {
{ /* COLOR_COPY */
NULL,
ACTIONS_LEFT,
ACTIONS_TOP + (0 * (ACTIONS_HEIGHT + 3)),
ACTIONS_WIDTH,
ACTIONS_HEIGHT,
GADGHCOMP,
RELVERIFY,
BOOLGADGET,
(APTR)&actions_border,
NULL,
&actions_text[0],
NULL,
NULL,
COLOR_COPY,
NULL,
},
{ /* COLOR_RANGE */
&gadglist[COLOR_COPY],
ACTIONS_LEFT,
ACTIONS_TOP + (01 * (ACTIONS_HEIGHT + 3)),
ACTIONS_WIDTH,
ACTIONS_HEIGHT,
GADGHCOMP,
RELVERIFY,
BOOLGADGET,
(APTR)&actions_border,
NULL,
&actions_text[01],
NULL,
NULL,
COLOR_RANGE,
NULL,
},
{ /* COLOR_OK */
&gadglist[COLOR_RANGE],
ACTIONS_LEFT,
ACTIONS_TOP + (02 * (ACTIONS_HEIGHT + 3)),
ACTIONS_WIDTH,
ACTIONS_HEIGHT,
GADGHCOMP,
RELVERIFY,
BOOLGADGET,
(APTR)&actions_border,
NULL,
&actions_text[02],
NULL,
NULL,
COLOR_OK,
NULL,
},
{ /* COLOR_CANCEL */
&gadglist[COLOR_OK],
ACTIONS_LEFT,
ACTIONS_TOP + (03 * (ACTIONS_HEIGHT + 3)),
ACTIONS_WIDTH,
ACTIONS_HEIGHT,
GADGHCOMP,
RELVERIFY,
BOOLGADGET,
(APTR)&actions_border,
NULL,
&actions_text[03],
NULL,
NULL,
COLOR_CANCEL,
NULL,
},
{ /* COLOR_GREEN */
&gadglist[COLOR_CANCEL],
PROP_LEFT,
PROP_TOP + (01 * (PROP_HEIGHT + 1)),
PROP_WIDTH,
PROP_HEIGHT,
GADGHCOMP | GADGIMAGE,
FOLLOWMOUSE,
PROPGADGET,
(APTR)&ColorPropsImages[01],
NULL,
NULL,
NULL,
(APTR)&ColorPropsInfos[01],
COLOR_GREEN,
NULL,
},
{ /* COLOR_RED */
&gadglist[COLOR_GREEN],
PROP_LEFT,
PROP_TOP + (00 * (PROP_HEIGHT + 1)),
PROP_WIDTH,
PROP_HEIGHT,
GADGHCOMP | GADGIMAGE,
FOLLOWMOUSE,
PROPGADGET,
(APTR)&ColorPropsImages[00],
NULL,
NULL,
NULL,
(APTR)&ColorPropsInfos[00],
COLOR_RED,
NULL,
},
{ /* COLOR_BLUE */
&gadglist[COLOR_RED],
PROP_LEFT,
PROP_TOP + (02 * (PROP_HEIGHT + 1)),
PROP_WIDTH,
PROP_HEIGHT,
GADGHCOMP | GADGIMAGE,
FOLLOWMOUSE,
PROPGADGET,
(APTR)&ColorPropsImages[02],
NULL,
NULL,
NULL,
(APTR)&ColorPropsInfos[02],
COLOR_BLUE,
NULL,
},
};
/*----------------------*/
/* Graphics definitions */
struct RastPort *rstport;
struct ViewPort *vp;
struct Window *ColorWindow;
/*****************************************************************************
*
* Color initialization and routines
*
****************************************************************************/
#define COPYCOLOR 1
#define RANGE_FIRST 2
#define RANGE_SECOND 3
USHORT ColorMode;
USHORT SavePalette[32];
#define COLOR_IDCMP_FLAGS (GADGETDOWN | GADGETUP | MOUSEBUTTONS \
| MENUPICK | MOUSEMOVE | ACTIVEWINDOW | INACTIVEWINDOW)
struct NewWindow ColorNewWindow =
{
WINDOW_LEFT, WINDOW_TOP,
WINDOW_WIDTH, WINDOW_HEIGHT,
-1, -1,
COLOR_IDCMP_FLAGS,
WINDOWDRAG | SMART_REFRESH | NOCAREREFRESH | ACTIVATE,
NULL, /* struct Gadget *FirstGadget; */
NULL, /* struct Image *CheckMark; */
"Modify Colours.", /* the title text for this window */
NULL, /* struct Screen *Screen; */
NULL, /* struct BitMap *BitMap; */
0, 0,
0, 0,
CUSTOMSCREEN, /* USHORT Type; */
};
USHORT RangeFirst; /* the first selection of the range-color pair */
/* ======================================================================== */
/* ======================================================================== */
BOOL OpenColorWindow(screen, colours)
struct Screen *screen;
short colours;
{
REGISTER LONG i;
ColorNewWindow.Screen = screen;
ColorNewWindow.FirstGadget=&gadglist[COLOR_GADGETS_COUNT - 1];
ColorMode = NULL;
if ( ! (ColorWindow = (struct Window *)OpenWindow(&ColorNewWindow)))
return(FALSE);
rstport = ColorWindow->RPort;
SetAPen(rstport, 1);
SetColorProps();
for (i = 0; i < 32; i++)
SavePalette[i] = GetRGB4(vp->ColorMap, i);
DrawColorWindow(colours);
return(TRUE);
}
VOID CloseColorWindow(accept)
BOOL accept;
{
if ( NOT ColorWindow)
return;
CloseWindow(ColorWindow);
ColorWindow = NULL;
if (NOT accept)
LoadRGB4(vp, &SavePalette[0], 32L);
}
VOID ColorRange(first, last)
SHORT first, last;
{
REGISTER SHORT i;
LONG whole, redfraction, greenfraction, bluefraction;
REGISTER USHORT rgb;
SHORT firstred, firstgreen, firstblue;
SHORT lastred, lastgreen, lastblue;
SHORT workred, workgreen, workblue;
if (first > last) {
i = first;
first = last;
last = i;
}
/* I need to see a spread of at least two, where there's at least one
* spot between the endpoints, else there's no work to do so I
* might as well just return now.
*/
if (first >= last - 1)
return;
rgb = GetRGB4(vp->ColorMap, (LONG)first);
firstred = (rgb >> 8) & 0xF;
firstgreen = (rgb >> 4) & 0xF;
firstblue = (rgb >> 0) & 0xF;
rgb = GetRGB4(vp->ColorMap, (LONG)last);
lastred = (rgb >> 8) & 0xF;
lastgreen = (rgb >> 4) & 0xF;
lastblue = (rgb >> 0) & 0xF;
whole = ((LONG) (lastred - firstred)) << 16;
redfraction = whole / (last - first);
whole = ((LONG)(lastgreen - firstgreen)) << 16;
greenfraction = whole / (last - first);
whole = ((LONG)(lastblue - firstblue)) << 16;
bluefraction = whole / (last - first);
for (i = first + 1; i < last; i++)
{
lastred = (redfraction * (i - first) + 0x8000) >> 16;
workred = firstred + lastred;
lastgreen = (greenfraction * (i - first) + 0x8000) >> 16;
workgreen = firstgreen + lastgreen;
lastblue = (bluefraction * (i - first) + 0x8000) >> 16;
workblue = firstblue + lastblue;
SetRGB4(vp, (LONG) i,(LONG)workred,(LONG)workgreen,(LONG)workblue);
}
}
BOOL colorchosen(pen)
short pen;
{
REGISTER USHORT rgb;
complementbox(rstport, rstport->FgPen);
complementbox(rstport, pen);
if (ColorMode == COPYCOLOR)
{
rgb = GetRGB4(vp->ColorMap, (LONG)rstport->FgPen);
SetRGB4(vp, pen, (rgb >> 8), (rgb >> 4), rgb );
ColorMode = NULL;
}
if (ColorMode == RANGE_FIRST)
{
ColorMode = RANGE_SECOND;
RangeFirst = pen;
}
else if (ColorMode == RANGE_SECOND)
{
ColorMode = NULL;
ColorRange(RangeFirst, pen);
}
SetAPen(rstport, (LONG)pen);
rgb = GetRGB4(vp->ColorMap, (LONG)pen);
ColorRectFill((LONG)pen);
SetColorProps();
}
BOOL GadgetGotten(gadgetnum)
short gadgetnum;
{
switch (gadgetnum)
{
case COLOR_OK:
CloseColorWindow(TRUE);
return(FALSE);
case COLOR_CANCEL:
CloseColorWindow(FALSE);
return(FALSE);
case COLOR_COPY:
ColorMode = COPYCOLOR;
break;
case COLOR_RANGE:
ColorMode = RANGE_FIRST;
break;
}
return(TRUE);
}
ModifyColors()
{
USHORT pen;
REGISTER USHORT newred, newgreen, newblue;
pen = rstport->FgPen;
newred = ((struct PropInfo *)
gadglist[COLOR_RED].SpecialInfo)->HorizPot >> 12;
newgreen = ((struct PropInfo *)
gadglist[COLOR_GREEN].SpecialInfo)->HorizPot >> 12;
newblue = ((struct PropInfo *)
gadglist[COLOR_BLUE].SpecialInfo)->HorizPot >> 12;
SetRGB4(vp, (LONG)pen, (LONG)newred, (LONG)newgreen, (LONG)newblue);
printcolors(newred, newgreen, newblue);
}
printcolors(red, green, blue)
USHORT red, green, blue;
{
char *buffer = " ";
sprintf(buffer, "%2d", red);
printtext(buffer, PROP_WIDTH + PROP_LEFT+2, CURRENT_TOP);
sprintf(buffer, "%2d", green);
printtext(buffer, PROP_WIDTH + PROP_LEFT+2, CURRENT_TOP+(PROP_HEIGHT+1));
sprintf(buffer, "%2d", blue);
printtext(buffer, PROP_WIDTH + PROP_LEFT+2, CURRENT_TOP
+ (PROP_HEIGHT+1) * 2);
}
DrawColorWindow(colours)
{
REGISTER SHORT i;
ColorRectFill((LONG)rstport->FgPen);
DrawBox(rstport, CURRENT_LEFT-2,CURRENT_TOP-2,CURRENT_RIGHT+2,CURRENT_BOTTOM+2);
DrawBox(rstport, CURRENT_LEFT-2, COLORS_TOP-2, CURRENT_LEFT+(8 * 15)+1,
COLORS_TOP + (4 * 10) + 1);
printtext("R", CURRENT_RIGHT + 6, CURRENT_TOP);
printtext("G", CURRENT_RIGHT + 6, CURRENT_TOP + PROP_HEIGHT+1);
printtext("B", CURRENT_RIGHT + 6, CURRENT_TOP + (PROP_HEIGHT+1)* 2);
for (i = 0; i < colours; i++)
{
ColorImage.PlaneOnOff = i;
DrawImage(rstport, &ColorImage, (i % 8) * 15, (i / 8) * 10);
}
complementbox(rstport, 1); /* starting colour is colour 1 */
}
SetColorProps()
{
USHORT rgb;
REGISTER USHORT red, green, blue;
SHORT greenpos, redpos, bluepos;
redpos = RemoveGadget(ColorWindow, &gadglist[COLOR_RED]);
greenpos = RemoveGadget(ColorWindow, &gadglist[COLOR_GREEN]);
bluepos = RemoveGadget(ColorWindow, &gadglist[COLOR_BLUE]);
rgb = GetRGB4(vp->ColorMap, (LONG)rstport->FgPen);
red = (rgb >> 8) & 0xF;
green = (rgb >> 4) & 0xF;
blue = (rgb >> 0) & 0xF;
((struct PropInfo *)gadglist[COLOR_RED].SpecialInfo)->HorizPot
= (red << 12) | (red << 8) | (red << 4) | red;
((struct PropInfo *)gadglist[COLOR_GREEN].SpecialInfo)->HorizPot
= (green << 12) | (green << 8) | (green << 4) | green;
((struct PropInfo *)gadglist[COLOR_BLUE].SpecialInfo)->HorizPot
= (blue << 12) | (blue << 8) | (blue << 4) | blue;
AddGadget(ColorWindow,&gadglist[COLOR_BLUE], (LONG)bluepos);
AddGadget(ColorWindow,&gadglist[COLOR_GREEN],(LONG)greenpos);
AddGadget(ColorWindow,&gadglist[COLOR_RED], (LONG)redpos);
RefreshGadgets(&gadglist[COLOR_GADGETS_COUNT-1],ColorWindow);
printcolors(red, green, blue);
}
ColorRectFill( pen)
LONG pen;
{
SetAPen(rstport, pen);
SetDrMd(rstport, JAM2);
WaitBOVP(vp);
RectFill(rstport, CURRENT_LEFT, CURRENT_TOP, CURRENT_RIGHT, CURRENT_BOTTOM);
}
VOID DoColorWindow(screen)
struct Screen *screen;
{
BOOL GadgetGotten(), OpenColorWindow();
REGISTER struct IntuiMessage *message;
REGISTER ULONG class;
REGISTER struct Gadget *gadget;
USHORT bitplanes, colours, code;
short number, x, y;
vp = &screen->ViewPort;
bitplanes = screen->BitMap.Depth;
for (colours = 1; bitplanes; bitplanes--)
colours *= 2;
if (colours > 32)
colours = 32;
if (NOT OpenColorWindow(screen, colours))
return;
FOREVER {
Wait((1L << ColorWindow->UserPort->mp_SigBit));
while (message = (struct IntuiMessage *)GetMsg(ColorWindow->UserPort)) {
class = message->Class;
code = message->Code;
x = message->MouseX;
y = message->MouseY;
if (class != MOUSEBUTTONS)
gadget = (struct Gadget *)(message->IAddress);
ReplyMsg(message);
switch (class) {
case GADGETDOWN:
case GADGETUP:
if ( NOT GadgetGotten(gadget->GadgetID))
return;
break;
case MOUSEBUTTONS:
if ( x >= CURRENT_LEFT && x < CURRENT_LEFT + 8 * 15)
if (y >= COLORS_TOP && y < COLORS_TOP + 4 * 10)
{
number = (x-CURRENT_LEFT)/15 + ((y-COLORS_TOP)/10)*8;
if (number < colours && code == SELECTDOWN)
colorchosen(number);
}
break;
case MOUSEMOVE:
ModifyColors();
break;
default:
break;
}
}
}
}
DrawBox(rp, x1, y1, x2, y2)
struct RastPort *rp;
short x1, y1, x2, y2;
/* draws a box without overlapping the edges (in case of complement mode) */
{
Move(rp, x1, y1 + SIGN(y2 - y1));
Draw(rp, x1, y2);
Move(rp, x1 + SIGN(x2 - x1), y2);
Draw(rp, x2, y2);
Move(rp, x2, y2 - SIGN(y2 - y1));
Draw(rp, x2, y1);
Move(rp, x2 - SIGN(x2 - x1), y1);
Draw(rp, x1, y1);
}
complementbox(rp, colours)
short colours;
{
short x, y;
x = CURRENT_LEFT + (colours % 8) * 15;
y = COLORS_TOP + (colours / 8) * 10;
SetDrMd(rp, COMPLEMENT);
DrawBox(rp, x, y, x + 14, y + 9);
SetDrMd(rp, JAM1);
}
printtext(text, x, y)
char *text;
short x, y;
{
string.IText = text;
PrintIText(rstport, &string, x, y);
}